package com.ttg.web.service.Impl;

import com.ttg.common.constant.BasicConstant;
import com.ttg.common.dto.BasicDto;
import com.ttg.common.entities.UserTokenInfo;
import com.ttg.common.enums.ErrorCodeEnums;
import com.ttg.common.enums.MobileSmsStatusEnum;
import com.ttg.common.enums.SwitchEnum;
import com.ttg.common.exception.BaseException;
import com.ttg.common.gxp.GxpUtil;
import com.ttg.common.utils.BasicUtils;
import com.ttg.common.utils.SecurityUtils;
import com.ttg.common.utils.UserUtil;
import com.ttg.model.dto.function.MobileSmsDTO;
import com.ttg.common.gxp.param.SrBankMessages;
import com.ttg.common.gxp.param.SrBankMessagesVO;
import com.ttg.common.gxp.param.SrBankPublicVO;
import com.ttg.model.pojo.MobileSms;
import com.ttg.model.pojo.SysConfig;
import com.ttg.web.service.FunctionService;
import com.ttg.web.service.MobileSmsService;
import com.ttg.web.service.SysConfigService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Objects;
import java.util.Optional;
import java.util.TreeMap;

/**
 * @author zzq
 * @version 1.0
 * @Description
 * @date 2021/3/17 10:39
 */
@Slf4j
@Service
public class FunctionServiceImpl implements FunctionService {

    @Autowired
    private MobileSmsService mobileSmsService;

    @Autowired
    private SysConfigService sysConfigService;
    /**
     * 验签 token方式
     */
    @Override
    public boolean verifySign(BasicDto organBaseDto){
        boolean signResult = false;
        try {
            TreeMap<String, String> verifyData = new TreeMap<>();
            String sign = organBaseDto.getSign();
            verifyData.put("lang",organBaseDto.getLang());
            verifyData.put("timestamp",organBaseDto.getTimestamp());
            if (StringUtils.isNotBlank(organBaseDto.getData())) {
                verifyData.put("data",organBaseDto.getData());
            }
            String sortedStr = BasicUtils.sort(verifyData);
            signResult = SecurityUtils.verifySignWithMd5(sign, sortedStr);
        } catch (Exception e) {
            log.error("验签异常",e);
        }
        return signResult;
    }


    @Override
    public Long mobileSms(MobileSmsDTO dto) {
        if (StringUtils.isBlank(dto.getSmsMobile())) {
            throw new BaseException(ErrorCodeEnums.DATA_ERROR);
        }
        UserTokenInfo user = Optional.ofNullable(UserUtil.getUser()).orElse(new UserTokenInfo());
        MobileSms sms = new MobileSms();
        sms.setSmsMobile(dto.getSmsMobile());
        if (StringUtils.isNotBlank(dto.getSmsIp())) {
            sms.setSmsIp(dto.getSmsIp());
        } else {
            sms.setSmsIp(Optional.ofNullable(user.getIp()).orElse(""));
        }
        sms.setSmsAddTime(LocalDateTime.now());
        sms.setSmsSendTime(LocalDateTime.now());
        sms.setSmsExpiredTime(dto.getSmsExpiredTime());
        sms.setSmsCode(dto.getSmsCode());
        sms.setSmsContent(dto.getSmsContent());
        sms.setSmsStatus(MobileSmsStatusEnum.TYPE_0.getValue());
        sms.setSmsChannel(dto.getSmsChannel());
        sms.setSmsCmd(dto.getSmsCmd());
        //mobile+ sms_type + content
        String sign = BasicUtils.MD5(dto.getSmsMobile() + dto.getSmsChannel() + dto.getSmsContent());
        sms.setSmsSign(sign);
        //校验一分钟内重发送
        if (dto.isNotCheck()) {
            LocalDateTime gtTime = LocalDateTime.now().plusMinutes(BasicConstant.LONG__1);
            int count = mobileSmsService.countByMobile(dto.getSmsMobile(), gtTime);
            if (count > BasicConstant.INT_0) {
                throw new BaseException("一分钟内只能发送一条手机短信，请勿重复提交");
            }
        }
        //超出今日发送限制
        LocalDate nowDate = LocalDate.now();
        LocalDateTime sDate = nowDate.atStartOfDay();
        LocalDateTime eDate = nowDate.plusDays(BasicConstant.LONG_1).atStartOfDay();
        int count = mobileSmsService.countByMobile(dto.getSmsMobile(), sDate, eDate);
        if (count > BasicConstant.INT_20) {
            throw new BaseException("每人每天最多只能发送20条短信");
        }
        mobileSmsService.save(sms);
        if (Objects.isNull(sms.getSmsId())) {
            throw new BaseException("发送消息失败");
        }
        //是否出现消息编号
        if (dto.isShowSmsId()) {
            MobileSms temp = new MobileSms();
            temp.setSmsId(sms.getSmsId());
            temp.setSmsContent("[" + sms.getSmsId() + "]"+ sms.getSmsContent());
            mobileSmsService.updateById(temp);
        }
        //是否立即发送
        if (dto.isSendNow()) {
            this.sendMobileSms(sms.getSmsId());
        } else {

        }
        return sms.getSmsId();
    }


    private void sendMobileSms(Long smsId) {
        MobileSms mobileSms = mobileSmsService.select1(smsId, 0);
        if (null == mobileSms) {
            return;
        }
        SrBankMessages srBankMessages = new SrBankMessages();
        srBankMessages.setMobileNo(mobileSms.getSmsMobile());
        srBankMessages.setMessgaeText(mobileSms.getSmsContent());
        srBankMessages.setSmsId(smsId);
        SrBankPublicVO<SrBankMessagesVO> srBankPublicVO = new SrBankPublicVO();
        SysConfig gxpSwitch = sysConfigService.getSysConfig("GXP_SWITCH");
        if (SwitchEnum.ON.getStatus().equals(gxpSwitch.getSysValue())) {
            srBankPublicVO = GxpUtil.srBankMessagesV2(srBankMessages);
        } else {
            //测试环境短信发送临时处理
            srBankPublicVO.setGxpRespCode("00000");
            srBankPublicVO.setBusiRespCode("00000");
            srBankPublicVO.setBusiRespMsg("交易成功");
            srBankPublicVO.setGxpRespMsg("交易成功");
        }

        if (Objects.isNull(srBankPublicVO)) {
            throw new BaseException(ErrorCodeEnums.GXP_ERROR);
        }
        MobileSms data = new MobileSms();
        if ("00000".equals(srBankPublicVO.getGxpRespCode()) && "00000".equals(srBankPublicVO.getBusiRespCode())) {
            data.setSmsStatus(MobileSmsStatusEnum.TYPE_1.getValue());
        } else {
            data.setSmsStatus(MobileSmsStatusEnum.TYPE_5.getValue());
        }
        if (Objects.nonNull(srBankPublicVO.getBody())) {
            data.setSmsResp(srBankPublicVO.getBody().getMsgId());
        }
        data.setSmsChannelTime(LocalDateTime.now());
        data.setSmsId(smsId);
        mobileSmsService.updateById(data);
    }
}
